package com.zb.jnlxc.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ZLHW.base.Exception.BaseErrorModel;
import com.ZLHW.base.Form.Page;
import com.ZLHW.base.dao.QueryCondition;
import com.zb.jnlxc.constants.OrderStateConst;
import com.zb.jnlxc.constants.ProcessConstants;
import com.zb.jnlxc.dao.*;
import com.zb.jnlxc.form.QueryProcessModel;
import com.zb.jnlxc.model.*;
import com.zb.util.MapUtils;
import com.zb.util.StringUtils;

@Transactional
@Service
public class ProduceFlowService {
    Logger                           logger = LoggerFactory.getLogger(ProduceFlowService.class);
    @Resource
    private LiaoKuangDAO             liaoKuangDAO;
    @Resource
    private OrderFormDAO             orderFormDAO;
    @Resource
    private TruckDAO                 truckDAO;
    @Resource
    private OrderDetailDAO           orderDetailDAO;
    @Resource
    private PaichanOrderDetailDAO    paichanOrderDetailDAO;
    @Resource
    private PaiChanRecordDAO         paiChanRecordDAO;
    @Resource
    private ProductDetailDAO         productDetailDAO;
    @Resource
    private ProductProcessDAO        productProcessDAO;
    @Resource
    private MouldDAO                 mouldDao;
    @Value("${print.server.url}")
    private String                   printServerUrl;
    @Value("${print.server.port}")
    private int                      printServerPort;
    @Resource
    FlowService                      flowService;
    @Resource
    AdminDAO                         adminDAO;

    public void getProductSituation(Page page, Integer mouldId) {
        Mould mould = mouldDao.getById(mouldId);
        List<QueryCondition> queryConditions = new ArrayList();
        StringBuffer hql = new StringBuffer(
                "from PaiChanRecord t where finished=false and jiYaFinished=false ");
        hql.append("and t.orderForm.scheme.dbId=:RefschemeId ");
        queryConditions.add(new QueryCondition("RefschemeId", mould.getScheme().getDbId()));
        hql.append("order by ").append(page.getSortKey()).append(" ").append(page.getSortOrder());
        paiChanRecordDAO.findByPageWithTmpHQL(page, hql.toString(), queryConditions);
    }

    /**
     * 获取工序记录
     * @param paichanRecordId
     * @return
     */
    public List<ProductProcess> getProductProcessByPaiChan(Integer paichanRecordId) {

        StringBuilder hql = new StringBuilder("from ProductProcess t where ");
        hql.append("t.productDetail.paichanOrderDetail.paichanRecord.dbId = ? ");
        hql.append("order by dbId asc");
        List<ProductProcess> productProcesses = productProcessDAO.findByHQL(hql.toString(),
                paichanRecordId);
        return productProcesses;
    }

    /**
     * 获取入库记录
     * @param orderId
     * @return
     */
    public List<ProductProcess> getStorateProcessByOrderId(Integer orderId) {

        StringBuilder hql = new StringBuilder("from ProductProcess t where ");
        hql.append("t.productDetail.paichanOrderDetail.paichanRecord.orderForm.dbId = ? and t.processName = ? ");
        hql.append("order by dbId asc");
        List<ProductProcess> productProcesses = productProcessDAO.findByHQL(hql.toString(),
                orderId, ProcessConstants.STORAGE);
        return productProcesses;
    }

    /**
     * 获取生产任务
     * @return
     */
    public Page loadLiaoKuang(Page page, String code, String currentStep) {
        List<QueryCondition> queryConditions = new ArrayList();
        StringBuffer hql = new StringBuffer("from LiaoKuang t where 1=1 ");
        if (StringUtils.isNotEmpty(currentStep)) {
            hql.append("and t.currentStep=:RefCurrentStep and used=true ");
            queryConditions.add(new QueryCondition("RefCurrentStep", currentStep));
        }
        if (StringUtils.isNotBlank(code)) {
            hql.append(" and t.code=:Refcode ");
            queryConditions.add(new QueryCondition("Refcode", code));
        }
        hql.append("order by ").append(page.getSortKey()).append(" ").append(page.getSortOrder());
        liaoKuangDAO.findByPageWithTmpHQL(page, hql.toString(), queryConditions);
        return page;
    }

    /**
     * 获取货车列表
     * @return
     */
    public Page loadTruck(Page page, String code) {
        List<QueryCondition> queryConditions = new ArrayList();
        StringBuffer hql = new StringBuffer("from Truck t where 1=1 ");
        if (StringUtils.isNotBlank(code)) {
            hql.append(" and t.code=:Refcode ");
            queryConditions.add(new QueryCondition("Refcode", code));
        }
        hql.append("order by ").append(page.getSortKey()).append(" ").append(page.getSortOrder());
        truckDAO.findByPageWithTmpHQL(page, hql.toString(), queryConditions);
        return page;
    }

    public List<LiaoKuang> searchLiaoKuang(String code, String currentStep) {
        StringBuffer hql = new StringBuffer("select t from LiaoKuang t where 1=1 ");
        hql.append("and ((t.currentStep=? and used=true) or(used=false)) ");
        hql.append(" and t.code like ? ");
        return liaoKuangDAO.findByHQLWithIndex(hql.toString(), 0, 10, currentStep, code + "%");
    }

    public List<Truck> searchTruck(String code) {
        return truckDAO.searchByCode(code);
    }

    public Integer getLiaoKuangWeight(Integer liaoKuangId) {
        return liaoKuangDAO.getLiaoKuangWeight(liaoKuangId);
    }

    public LiaoKuang getLiaoKuang(Integer liaoKuangId) {
        return liaoKuangDAO.getById(liaoKuangId);
    }

    public float getTheoryWeight(Integer yangHuaId) {
        return productProcessDAO.getTheoryWeight(yangHuaId);
    }

    public float getDeliveryaWeight(Integer deliveryId) {
        return productProcessDAO.getDeliveryaWeight(deliveryId);
    }

    /**
     * 料框过磅
     */
    public void liaoKuangWeight(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess lastProcess = productProcessDAO.getById(lastProcessId);
        ProductProcess guobang = new ProductProcess();
        if (StringUtils.isNotBlank(form.get("currentProcessId"))) {
            guobang = productProcessDAO.getById(Integer.parseInt(form.get("currentProcessId")));
        }
        guobang.setProductDetail(lastProcess.getProductDetail());
        guobang.setProcessName(ProcessConstants.GUOBANG);

        guobang.setLastProcessId(lastProcess.getDbId());
        guobang.setOperator(admin);
        guobang.setFinished(false);
        guobang.setCreateDate(new Date());
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        int defectiveQuantity = MapUtils.getInt(form, "defectiveQuantity", "不合格数量不能为空");
        if ((quantity + defectiveQuantity) != lastProcess.getUncompQuantity().intValue()) {
            throw new BaseErrorModel("过磅数量有误 总共：" + lastProcess.getUncompQuantity() + "条", "");
        }
        guobang.setDefectiveQuantity(defectiveQuantity);
        guobang.setQuantity(quantity);
        guobang.setUncompQuantity(quantity);
        guobang.setCompQuantity(0);

        productProcessDAO.create(guobang);
    }

    /**
     * 完成过磅工序
     */
    public void weightFinish(Integer liaoKuangId, Map<String, String> form, Admin admin) {
        LiaoKuang liaoKuang = liaoKuangDAO.getById(liaoKuangId);
        String nextStep = liaoKuang.getNextStep();
        liaoKuang.setCurrentStep(nextStep);
        liaoKuangDAO.update(liaoKuang);

        List<ProductProcess> list = productProcessDAO.getByLiaoKuangId(liaoKuangId);
        for (ProductProcess productProcess : list) {
            List<ProductProcess> weightProcesses = productProcessDAO.getByColumn("lastProcessId",
                    productProcess.getDbId());
            if (CollectionUtils.isEmpty(weightProcesses)) {
                throw new BaseErrorModel("所有记录保存后才能完成过磅");
            }
            ProductProcess guobang = weightProcesses.get(0);
            guobang.setLiaoKuang(liaoKuang);

            guobang.setRealWeight(MapUtils.getInt(form, "realWeight", "实际重量不为空"));
            guobang.setTheoryWeight(MapUtils.getInt(form, "theoryWeight", "理论重量不为空"));
            guobang.setGtQuantity(MapUtils.getInt(form, "gtQuantity", "隔条数量不为空"));
            guobang.setTotalWeight(MapUtils.getInt(form, "totalWeight", "总重量不为空"));

            productProcessDAO.update(guobang);
            productProcessDAO.updateLastProcess(guobang, productProcess);
            paichanOrderDetailDAO.updatePaiChanUnComplete(guobang);
        }
    }

    /**
     * 产品时效
     */
    public void shixiao(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess lastProcess = productProcessDAO.getById(lastProcessId);
        ProductProcess productDetailShiXiao = new ProductProcess();
        if (StringUtils.isNotBlank(form.get("currentProcessId"))) {
            productDetailShiXiao = productProcessDAO.getById(Integer.parseInt(form
                    .get("currentProcessId")));
        }
        //等统一完成以后，再设置料框
        productDetailShiXiao.setProcessName(ProcessConstants.SHIXIAO);
        productDetailShiXiao.setProductDetail(lastProcess.getProductDetail());
        productDetailShiXiao.setLastProcessId(lastProcess.getDbId());

        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        int defectiveQuantity = MapUtils.getInt(form, "defectiveQuantity", "不合格数量不能为空");
        if ((quantity + defectiveQuantity) != lastProcess.getUncompQuantity().intValue()) {
            throw new BaseErrorModel("时效数量有误 总共：" + lastProcess.getUncompQuantity() + "条", "");
        }
        productDetailShiXiao.setDefectiveQuantity(defectiveQuantity);
        productDetailShiXiao.setUncompQuantity(quantity);
        productDetailShiXiao.setQuantity(quantity);

        productDetailShiXiao
                .setAginghardness(MapUtils.getString(form, "aginghardness", "时效硬度不能为空"));
        productDetailShiXiao.setHoldingTemperature(MapUtils.getString(form, "holdingTemperature",
                "保温温度不能为空"));
        productDetailShiXiao.setShixiaoluhao(MapUtils.getString(form, "shixiaoluhao", "时效炉号不能为空"));
        Date comeInTime = MapUtils.getDate(form, "comeInTime", "时效进炉时间有误");
        Date comeOutTime = MapUtils.getDate(form, "comeOutTime", "时效出炉时间有误");
        productDetailShiXiao.setComeInTime(comeInTime);
        productDetailShiXiao.setComeOutTime(comeOutTime);

        productDetailShiXiao.setOperator(admin);
        productDetailShiXiao.setCreateDate(new Date());
        productDetailShiXiao.setFinished(false);
        productProcessDAO.update(productDetailShiXiao);
    }

    /**
     * 完成时效工序
     */
    public void shixiaoFinish(Integer liaoKuangId, Admin admin) {
        LiaoKuang liaoKuang = liaoKuangDAO.getById(liaoKuangId);
        String nextStep =null;
        List<ProductProcess> list = productProcessDAO.getByLiaoKuangId(liaoKuangId);
        for (ProductProcess productProcess : list) {
            List<ProductProcess> shiXiaoProcess = productProcessDAO.getByColumn("lastProcessId",
                    productProcess.getDbId());
            if (CollectionUtils.isEmpty(shiXiaoProcess)) {
                throw new BaseErrorModel("所有记录保存后才能完成时效");
            }
            ProductProcess shixiaoProcess = shiXiaoProcess.get(0);

            ProductDetail productDetail = shixiaoProcess.getProductDetail();
            PaichanOrderDetail paichanOrderDetail = productDetail.getPaichanOrderDetail();
            int ratio = paichanOrderDetail.getPaichanSize()/paichanOrderDetail.getSetSize();
            if(StringUtils.isBlank(liaoKuang.getNextStep())){
                if(productDetail.getPaichanOrderDetail().getJingju()==true){
                    nextStep = ProcessConstants.JINGJU;
                    shixiaoProcess.setUncompQuantity(productProcess.getQuantity()*ratio);
                }else {
                    nextStep = StringUtils.isBlank(nextStep)?ProcessConstants.STORAGE:nextStep;
                    shixiaoProcess.setUncompQuantity(productProcess.getQuantity());
                }
            }else {
                nextStep = liaoKuang.getNextStep();
            }

            shixiaoProcess.setLiaoKuang(liaoKuang);
            productProcessDAO.update(shixiaoProcess);
            productProcessDAO.updateLastProcess(shixiaoProcess, productProcess);
            paichanOrderDetailDAO.updatePaiChanUnComplete(shixiaoProcess);
        }
        liaoKuang.setCurrentStep(nextStep);
        liaoKuangDAO.update(liaoKuang);
    }

    /**
     * 喷涂
     */
    public void pengtu(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess productProcess = productProcessDAO.getById(lastProcessId);
        LiaoKuang liaoKuang = productProcess.getLiaoKuang();
        ProductProcess pengtu = new ProductProcess();
        ProductDetail productDetail = productProcess.getProductDetail();
        pengtu.setProductDetail(productDetail);
        pengtu.setLastProcessId(lastProcessId);
        pengtu.setCreateDate(new Date());
        pengtu.setOperator(admin);
        pengtu.setProcessName(ProcessConstants.PENGTU);
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        pengtu.setUncompQuantity(quantity);
        pengtu.setQuantity(quantity);
        pengtu.setShangPaiDefectiveQuantity(MapUtils.getInt(form, "shangPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        pengtu.setXiaPaiDefectiveQuantity(MapUtils.getInt(form, "xiaPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        pengtu.setDefectiveQuantity(pengtu.getShangPaiDefectiveQuantity()
                + pengtu.getXiaPaiDefectiveQuantity());

        pengtu.setOxideFilm(MapUtils.getString(form, "oxideFilm", "不合格数量必须是整数"));
        String liaoKuangcode = MapUtils.getString(form, "liaoKuangCode", "料框不能为空");
        pengtu.setFinished(false);
        setLiaoKuang(pengtu,quantity,liaoKuangcode,liaoKuang,liaoKuang.getNextStep());

        productProcessDAO.create(pengtu);
        productProcessDAO.updateLastProcess(pengtu, productProcess);
        paichanOrderDetailDAO.updatePaiChanUnComplete(pengtu);
        clearLiaoKuang(productProcess);
    }



    /**
     * 氧化
     */
    public void yanghua(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess productProcess = productProcessDAO.getById(lastProcessId);
        LiaoKuang liaoKuang = productProcess.getLiaoKuang();
        ProductProcess yangHua = new ProductProcess();
        ProductDetail productDetail = productProcess.getProductDetail();
        yangHua.setProductDetail(productDetail);
        yangHua.setLastProcessId(lastProcessId);
        yangHua.setCreateDate(new Date());
        yangHua.setOperator(admin);

        yangHua.setProcessName(ProcessConstants.YANGHUA);
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        yangHua.setUncompQuantity(quantity);
        yangHua.setQuantity(quantity);
        yangHua.setShangPaiDefectiveQuantity(MapUtils.getInt(form, "shangPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        yangHua.setXiaPaiDefectiveQuantity(MapUtils.getInt(form, "xiaPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        yangHua.setDefectiveQuantity(yangHua.getShangPaiDefectiveQuantity()
                + yangHua.getXiaPaiDefectiveQuantity());

        yangHua.setOxideFilm(MapUtils.getString(form, "oxideFilm", "不合格数量必须是整数"));
        String liaoKuangcode = MapUtils.getString(form, "liaoKuangCode", "料框不能为空");
        yangHua.setFinished(false);
        setLiaoKuang(yangHua,quantity,liaoKuangcode,liaoKuang,liaoKuang.getNextStep());

        productProcessDAO.create(yangHua);
        productProcessDAO.updateLastProcess(yangHua, productProcess);
        paichanOrderDetailDAO.updatePaiChanUnComplete(yangHua);
        //料框上的料全部上排以后，料框被制空，可重新参加挤压生产
        clearLiaoKuang(productProcess);
    }

    /**
     * 喷砂
     */
    public void pengsha(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess productProcess = productProcessDAO.getById(lastProcessId);
        LiaoKuang liaoKuang = productProcess.getLiaoKuang();
        ProductProcess pensha = new ProductProcess();
        ProductDetail productDetail = productProcess.getProductDetail();
        pensha.setProductDetail(productDetail);
        pensha.setLastProcessId(lastProcessId);
        pensha.setCreateDate(new Date());
        pensha.setOperator(admin);

        pensha.setProcessName(ProcessConstants.PENGSHA);
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        pensha.setUncompQuantity(quantity);
        pensha.setQuantity(quantity);
        pensha.setShangPaiDefectiveQuantity(MapUtils.getInt(form, "shangPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        pensha.setXiaPaiDefectiveQuantity(MapUtils.getInt(form, "xiaPaiDefectiveQuantity",
                "不合格数量必须是整数"));
        pensha.setDefectiveQuantity(pensha.getShangPaiDefectiveQuantity()
                + pensha.getXiaPaiDefectiveQuantity());

        pensha.setOxideFilm(MapUtils.getString(form, "oxideFilm", "不合格数量必须是整数"));
        String liaoKuangcode = MapUtils.getString(form, "liaoKuangCode", "料框不能为空");
        pensha.setFinished(false);
        setLiaoKuang(pensha,quantity,liaoKuangcode,liaoKuang,liaoKuang.getNextStep());

        productProcessDAO.create(pensha);
        productProcessDAO.updateLastProcess(pensha, productProcess);
        paichanOrderDetailDAO.updatePaiChanUnComplete(pensha);
        //料框上的料全部上排以后，料框被制空，可重新参加挤压生产
        clearLiaoKuang(productProcess);
    }

    /**
     * 打包
     */
    public void pack(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess lastProcess = productProcessDAO.getById(lastProcessId);
        LiaoKuang liaoKuang = lastProcess.getLiaoKuang();
        ProductProcess packRecord = new ProductProcess();
        packRecord.setProcessName(ProcessConstants.PACKAGE);
        ProductDetail productDetail = lastProcess.getProductDetail();
        packRecord.setProductDetail(productDetail);
        packRecord.setRealWeight(MapUtils.getInt(form, "weight", " 实际重量不能为空"));
        packRecord.setOperator(admin);
        String liaoKuangcode = MapUtils.getString(form, "liaoKuangCode", "料框不能为空");

        packRecord.setPackTheoryWeight(MapUtils.getLong(form, "theoryWeight", "理论重量不能为空"));
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        int defectiveQuantity = MapUtils.getInt(form, "defectiveQuantity", "不合格数量不能为空");
        if ((quantity + defectiveQuantity) > lastProcess.getUncompQuantity()) {
            throw new BaseErrorModel("打包最多" + lastProcess.getUncompQuantity() + "条", "");
        }
        long lastPackCount = MapUtils.getLong(form, "lastPackCount", "最后一包数量");
        long packageCount = MapUtils.getLong(form, "packageCount", "总包数");
        long quantityPerPackage = MapUtils.getLong(form, "quantityPerPackage", "单包条数");
        packRecord.setLastPackCount(lastPackCount);
        packRecord.setPackageCount(packageCount);
        packRecord.setQuantityPerPackage(quantityPerPackage);
        packRecord.setQuantity(quantity);
        packRecord.setDefectiveQuantity(defectiveQuantity);
        packRecord.setCreateDate(new Date());
        packRecord.setFinished(false);
        packRecord.setProductDetail(lastProcess.getProductDetail());
        packRecord.setLastProcessId(lastProcess.getDbId());

        setLiaoKuang(packRecord,quantity,liaoKuangcode,liaoKuang,liaoKuang.getNextStep());
        productProcessDAO.create(packRecord);
        productProcessDAO.updateLastProcess(packRecord, lastProcess);
        paichanOrderDetailDAO.updatePaiChanUnComplete(packRecord);
        clearLiaoKuang(lastProcess);
    }

    /**
     * 精锯
     */
    public void jingju(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess lastProcess = productProcessDAO.getById(lastProcessId);
        ProductProcess jingju = new ProductProcess();
        jingju.setProcessName(ProcessConstants.JINGJU);
        jingju.setRealWeight(MapUtils.getInt(form, "weight", " 实际重量不能为空"));
        jingju.setOperator(admin);
        String liaoKuangcode = MapUtils.getString(form, "liaoKuangCode", "料框不能为空");
        jingju.setLiaoKuang(getLiaoKuangByCode(liaoKuangcode, ProcessConstants.STORAGE, ""));
        jingju.setPackTheoryWeight(MapUtils.getLong(form, "theoryWeight", "理论重量不能为空"));
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        int defectiveQuantity = MapUtils.getInt(form, "defectiveQuantity", "不合格数量不能为空");
        if ((quantity + defectiveQuantity) > lastProcess.getUncompQuantity()) {
            throw new BaseErrorModel("打包最多" + lastProcess.getUncompQuantity() + "条", "");
        }
        long lastPackCount = MapUtils.getLong(form, "lastPackCount", "最后一包数量");
        long packageCount = MapUtils.getLong(form, "packageCount", "总包数");
        long quantityPerPackage = MapUtils.getLong(form, "quantityPerPackage", "单包条数");
        jingju.setLastPackCount(lastPackCount);
        jingju.setPackageCount(packageCount);
        jingju.setQuantityPerPackage(quantityPerPackage);
        jingju.setQuantity(quantity);
        jingju.setUncompQuantity(quantity);
        jingju.setDefectiveQuantity(defectiveQuantity);
        jingju.setCreateDate(new Date());
        jingju.setFinished(false);
        jingju.setProductDetail(lastProcess.getProductDetail());
        jingju.setLastProcessId(lastProcess.getDbId());
        productProcessDAO.create(jingju);
        productProcessDAO.updateLastProcess(jingju, lastProcess);
        paichanOrderDetailDAO.updatePaiChanUnComplete(jingju);
        clearLiaoKuang(lastProcess);
    }

    /**
     * 入库
     */
    public void storageFinish(Integer liaoKuangId, Map<String, String> form, Admin admin) {
        String storePlace = MapUtils.getString(form, "storePlace", "入库地址不能为空");
        LiaoKuang liaoKuang = liaoKuangDAO.getById(liaoKuangId);
        liaoKuang.setCurrentStep(ProcessConstants.DELIVER);
        liaoKuang.setCurrentPlace(storePlace);
        liaoKuangDAO.update(liaoKuang);

        List<ProductProcess> list = productProcessDAO.getByLiaoKuangId(liaoKuangId);
        for (ProductProcess productProcess : list) {
            ProductProcess storage = new ProductProcess();
            storage.setLiaoKuang(productProcess.getLiaoKuang());
            storage.setQuantity(productProcess.getQuantity());
            storage.setUncompQuantity(productProcess.getQuantity());
            storage.setRealWeight(productProcess.getRealWeight());
            storage.setCompQuantity(0);
            storage.setStorePlace(storePlace);
            storage.setProcessName(ProcessConstants.STORAGE);
            storage.setLastProcessId(productProcess.getDbId());
            storage.setOperator(admin);
            storage.setCreateDate(new Date());
            storage.setFinished(false);
            storage.setProductDetail(productProcess.getProductDetail());
            productProcessDAO.create(storage);
            productProcessDAO.updateLastProcess(storage, productProcess);

            updateOrderDetail(productProcess.getProductDetail().getPaichanOrderDetail().getOrderDetail());
            checkPaichanFinished(productProcess.getProductDetail().getPaichanOrderDetail().getDbId());
        }
    }

    /**
     * 发货
     */
    public void deliver(Integer lastProcessId, Map<String, String> form, Admin admin) {
        ProductProcess lastProcess = productProcessDAO.getById(lastProcessId);
        ProductProcess deliveRecord = new ProductProcess();
        deliveRecord.setProcessName(ProcessConstants.DELIVER);
        deliveRecord.setDeliveWeight(MapUtils.getLong(form, "deliveWeight", " 实际重量不能为空"));
        deliveRecord.setOperator(admin);
        String truckCode = MapUtils.getString(form, "truckCode", "车牌不能为空");
        Truck truck = truckDAO.getBycode(truckCode);
        if (truck == null) {
            throw new BaseErrorModel("货车编号不存在", "");
        }
        deliveRecord.setTruck(truck);
        deliveRecord.setDelivePackCount(MapUtils.getLong(form, "delivePackCount", "打包数量不能为空"));
        int quantity = MapUtils.getInt(form, "quantity", "实际数量不能为空");
        if (quantity > lastProcess.getUncompQuantity()) {
            throw new BaseErrorModel("打包最多" + lastProcess.getUncompQuantity() + "条", "");
        }
        deliveRecord.setQuantity(quantity);
        deliveRecord.setUncompQuantity(quantity);
        deliveRecord.setCreateDate(new Date());
        deliveRecord.setFinished(false);
        deliveRecord.setProductDetail(lastProcess.getProductDetail());
        deliveRecord.setLastProcessId(lastProcess.getDbId());
        productProcessDAO.create(deliveRecord);
        productProcessDAO.updateLastProcess(deliveRecord, lastProcess);
        clearLiaoKuang(lastProcess);
    }

    /**
     * 设置料框
     * @param current
     * @param quantity
     * @param liaoKuangcode
     * @param liaoKuang
     */
    private String setLiaoKuang(ProductProcess current,int quantity,String liaoKuangcode,LiaoKuang liaoKuang,String next){
        if(StringUtils.isBlank(next)){
            ProductDetail productDetail = current.getProductDetail();
            PaichanOrderDetail paichanOrderDetail = productDetail.getPaichanOrderDetail();
            int ratio = paichanOrderDetail.getPaichanSize()/paichanOrderDetail.getSetSize();
            if(paichanOrderDetail.getJingju()!=null&&paichanOrderDetail.getJingju()==true){
                next = ProcessConstants.JINGJU;
                current.setLiaoKuang(getLiaoKuangByCode(liaoKuangcode, next, ""));
                current.setUncompQuantity(quantity*ratio);
            }else {
                next = ProcessConstants.STORAGE;
                current.setLiaoKuang(getLiaoKuangByCode(liaoKuangcode, next, ""));
                current.setUncompQuantity(quantity);
            }

        }else {
            current.setLiaoKuang(getLiaoKuangByCode(liaoKuangcode, next,
                    liaoKuang.getNextSteps()));
        }
        return next;
    }

    /**
     * 清理料框
     */
    private void clearLiaoKuang(ProductProcess lastProcess) {
        if (productProcessDAO.liaoKuangUnUsed(lastProcess.getLiaoKuang().getDbId())) {
            lastProcess.getLiaoKuang().setCurrentStep("");
            lastProcess.getLiaoKuang().setSteps("");
            lastProcess.getLiaoKuang().setUsed(false);
            liaoKuangDAO.update(lastProcess.getLiaoKuang());
        }
    }

    /**
     * 判断订单排产是否结束
     * @param paichanOrderDetailId
     */
    private void checkPaichanFinished(Integer paichanOrderDetailId) {
        PaichanOrderDetail paichanOrderDetail = paichanOrderDetailDAO
                .loadById(paichanOrderDetailId);
        //相关产品明细全部完成
        if (productProcessDAO.canFinishPaiChanDetial(paichanOrderDetail.getDbId())) {
            paichanOrderDetail.setFinished(true);
            paichanOrderDetailDAO.update(paichanOrderDetail);
            List<PaichanOrderDetail> paichanOrderDetails = paichanOrderDetailDAO.findByHQL(
                    "from PaichanOrderDetail t where t.paichanRecord=? and finished=false",
                    paichanOrderDetail.getPaichanRecord());
            //排产的明细全部完成
            if (CollectionUtils.isEmpty(paichanOrderDetails)) {
                PaiChanRecord paiChanRecord = paiChanRecordDAO.loadById(paichanOrderDetail
                        .getPaichanRecord().getDbId());
                paiChanRecord.setFinished(true);
                paiChanRecordDAO.update(paiChanRecord);
                List<PaiChanRecord> paiChanRecordList = paiChanRecordDAO.findByHQL(
                        "from PaiChanRecord t where t.orderForm=? and t.finished = ?",
                        paiChanRecord.getOrderForm(), false);
                //订单未全部完成
                if (CollectionUtils.isNotEmpty(paiChanRecordList)) {
                    logger
                            .info("排产的订单未全部完成 orderFormId={}", paiChanRecord.getOrderForm().getDbId());
                    return;
                }

                //有处于打包，挤压之间的流程
                if (!productProcessDAO.canFinishOrder(paiChanRecord.getOrderForm().getDbId())) {
                    logger.info("有处于打包，挤压之间的流程 orderFormId={}", paiChanRecord.getOrderForm()
                            .getDbId());
                    return;
                }

                //明细不足
                if (!isQuantityEnough(paiChanRecord.getOrderForm())) {
                    logger.info("生产明细未超过订单明细 orderFormId={}", paiChanRecord.getOrderForm()
                            .getDbId());
                    return;
                }
                OrderForm orderForm = orderFormDAO.loadById(paiChanRecord.getOrderForm().getDbId());
                orderForm.setCurrentState(OrderStateConst.ORDER_FINISHED);
                orderFormDAO.update(orderForm);
            }
        }
    }


    public void updateOrderDetail(OrderDetail orderDetail){
        Map<String,Integer> map = productProcessDAO.getTotalByOrderDetail(orderDetail);
        int totalQuantity = map.get("totalQuantity");
        int totalWeight = map.get("totalWeight");
        orderDetail.setCompQuantity(totalQuantity);
        orderDetail.setCompWeight(totalWeight);
        if (totalQuantity < orderDetail.getOrderQuantity()) {
            orderDetail.setCompStatus((byte)0);
        }else{
            orderDetail.setCompStatus((byte)1);
        }
        orderDetailDAO.update(orderDetail);
    }

    private boolean isQuantityEnough(OrderForm orderForm) {
        List<OrderDetail> orderDetails = orderDetailDAO.getByOrderForm(orderForm);
        for (OrderDetail orderDetail : orderDetails) {
            if(orderDetail.getCompStatus()==0){
                return false;
            }
        }
        return true;
    }

    private LiaoKuang getLiaoKuangByCode(String code, String currentstep, String steps) {
        //修改料框状态
        LiaoKuang liaoKuang = liaoKuangDAO.getBycode(code);
        if (liaoKuang == null) {
            throw new BaseErrorModel("料框编号不存在");
        } else {
            if (liaoKuang.getUsed() && !currentstep.equals(liaoKuang.getCurrentStep())) {
                throw new BaseErrorModel("料框:" + liaoKuang.getCode() + " 处于{"
                        + liaoKuang.getCurrentStep() + "}状态，无法一起处理", "");
            } else {
                liaoKuang.setCurrentStep(currentstep);
                liaoKuang.setSteps(steps);
                liaoKuang.setUsed(true);
                liaoKuangDAO.update(liaoKuang);
                return liaoKuang;
            }
        }
    }

    public List<ProductProcess> getByLiaoKuang(Integer liaoKuangId) {
        if (liaoKuangId == null) {
            return null;
        }
        List<ProductProcess> yangHuaList = productProcessDAO.getByLiaoKuangId(liaoKuangId);
        return yangHuaList;
    }

    public List<QueryProcessModel> getQueryModelByLiaoKuang(Integer liaoKuangId) {
        if (liaoKuangId == null) {
            return null;
        }
        List<QueryProcessModel> shiXiaoModels = new ArrayList<QueryProcessModel>();
        List<ProductProcess> list = productProcessDAO.getByLiaoKuangId(liaoKuangId);
        for (ProductProcess productProcess : list) {
            QueryProcessModel shiXiaoModel = new QueryProcessModel();
            ProductDetail productDetail = productProcess.getProductDetail();
            shiXiaoModel.setLastProcess(productProcess);
            shiXiaoModel.setOrderFormCode(productDetail.getPaichanOrderDetail().getOrderDetail()
                    .getOrderForm().getCode());
            shiXiaoModel.setPaichanSize(productDetail.getPaichanOrderDetail().getPaichanSize());
            ProductProcess productDetailShiXiao = productProcessDAO.getByLassProcess(productProcess
                    .getDbId());
            shiXiaoModel.setCurrentProcess(productDetailShiXiao);
            shiXiaoModels.add(shiXiaoModel);
        }
        return shiXiaoModels;
    }

    public void deleteLiaoKuang(int dbId) {
        liaoKuangDAO.deleteById(dbId);
    }

    public void deleteTruck(int dbId) {
        truckDAO.deleteById(dbId);
    }

    public void updateLiaoKuang(LiaoKuang liaoKuang) {
        if (liaoKuang.getDbId() != null) {
            LiaoKuang dbLiaoKuang = liaoKuangDAO.loadById(liaoKuang.getDbId());
            dbLiaoKuang.setWeight(liaoKuang.getWeight());
            dbLiaoKuang.setCode(liaoKuang.getCode());
            dbLiaoKuang.setUpdateTime(new Date());
            liaoKuangDAO.update(dbLiaoKuang);
        } else {
            if (liaoKuangDAO.getBycode(liaoKuang.getCode()) == null) {
                liaoKuang.setUpdateTime(new Date());
                liaoKuang.setSteps("");
                liaoKuang.setUsed(false);
                liaoKuangDAO.create(liaoKuang);
            } else {
                throw new BaseErrorModel("料框编号已存在");
            }

        }

    }

    public void updateTruck(Truck truck) {
        if (truck.getDbId() != null) {
            Truck dbTruck = truckDAO.loadById(truck.getDbId());
            dbTruck.setCode(truck.getCode());
            dbTruck.setUpdateTime(new Date());
            truckDAO.update(dbTruck);
        } else {
            if (liaoKuangDAO.getBycode(truck.getCode()) == null) {
                truck.setUpdateTime(new Date());
                truck.setUsed(false);
                truckDAO.create(truck);
            } else {
                throw new BaseErrorModel("货车编号已存在");
            }

        }

    }

}
